﻿using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;

namespace HostingDemo
{
    public interface IProcessorMetricsCollector
    {
        int GetProcessorUsage();
    }
    public interface IMemoryMetricsCollector
    {
        long GetMemoryUsage();
    }
    public interface INetworkMetricsCollector
    {
        long GetNetworkUsage();
    }

    public interface IMetricsDeliver
    {
        Task DeliverAsync(PerformanceMetrics metrics);
    }




    public class FakeMetricsCollector : IProcessorMetricsCollector, IMemoryMetricsCollector, INetworkMetricsCollector
    {
        public long GetMemoryUsage()
        {
            return PerformanceMetrics.Create().Memory;
        }

        public long GetNetworkUsage()
        {
            return PerformanceMetrics.Create().Network;
        }

        public int GetProcessorUsage()
        {
            return PerformanceMetrics.Create().Processor;
        }
    }
    public class FakeMetricsDeliver : IMetricsDeliver
    {
        private readonly TransportType _transport;
        private readonly EndPoint _deliverTo;

        public FakeMetricsDeliver(IOptions<MetricsCollectorOption> options)
        {
            _transport = options.Value.TransportType;
            _deliverTo = options.Value.DeliverTo;
        }

        public Task DeliverAsync(PerformanceMetrics metrics)
        {
            Console.WriteLine($"{DateTime.Now.ToString()}  {metrics.ToString()}, {_deliverTo}  {_transport}");
            return Task.CompletedTask;
        }
    }


    public class PerformanceMetricsCollector2 : IHostedService
    {
        private readonly IProcessorMetricsCollector _processorMetricsCollector;
        private readonly IMemoryMetricsCollector _memoryMetricsCollector;
        private readonly INetworkMetricsCollector _networkMetricsCollector;
        private readonly IMetricsDeliver _metricsDeliver;
        private readonly TimeSpan _captureInterval;
        private IDisposable scheduler = null;

        public PerformanceMetricsCollector2(IProcessorMetricsCollector processorMetricsCollector,
            IMemoryMetricsCollector memoryMetricsCollector,
            INetworkMetricsCollector networkMetricsCollector,
            IMetricsDeliver metricsDeliver,
            IOptions<MetricsCollectorOption> options)
        {
            _processorMetricsCollector = processorMetricsCollector;
            _memoryMetricsCollector = memoryMetricsCollector;
            _networkMetricsCollector = networkMetricsCollector;
            _metricsDeliver = metricsDeliver;
            _captureInterval = options.Value.CaptureInterval;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            scheduler = new Timer(async state =>
            {
                var counter = new PerformanceMetrics
                {
                    Memory = _memoryMetricsCollector.GetMemoryUsage(),
                    Network = _networkMetricsCollector.GetNetworkUsage(),
                    Processor = _processorMetricsCollector.GetProcessorUsage()
                };
                await _metricsDeliver.DeliverAsync(counter);

            }, null, TimeSpan.FromSeconds(5), _captureInterval);
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            scheduler?.Dispose();
            return Task.CompletedTask;
        }



    }
}
